package com.marinesky.web.common.csrf;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/*
                   _ooOoo_
                  o8888888o
                  88" . "88
                  (| -_- |)
                  O\  =  /O
               ____/`---'\____
             .'  \\|     |//  `.
            /  \\|||  :  |||//  \
           /  _||||| -:- |||||-  \
           |   | \\\  -  /// |   |
           | \_|  ''\---/''  |   |
           \  .-\__  `-`  ___/-. /
         ___`. .'  /--.--\  `. . __
      ."" '<  `.___\_<|>_/___.'  >'"".
     | | :  `- \`.;`\ _ /`;.`/ - ` : | |
     \  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======
                   `=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         佛祖保佑       永无BUG
//          佛曰:
//                  写字楼里写字间，写字间里程序员；
//                  程序人员写程序，又拿程序换酒钱。
//                  酒醒只在网上坐，酒醉还来网下眠；
//                  酒醉酒醒日复日，网上网下年复年。
//                  但愿老死电脑间，不愿鞠躬老板前；
//                  奔驰宝马贵者趣，公交自行程序员。
//                  别人笑我忒疯癫，我笑自己命太贱；
//                  不见满街漂亮妹，哪个归得程序员？
/
                     Created by Marinesky on 2017/6/7.
 */
public class CsrfInterceptor extends HandlerInterceptorAdapter {

    private  final Logger logger = Logger.getLogger(getClass());

    @Resource
    private CsrfTokenRepository csrfTokenRepository;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if(handler instanceof HandlerMethod){

            HandlerMethod handlerMethod = (HandlerMethod) handler;

            CsrfToken csrfToken = handlerMethod.getMethodAnnotation(CsrfToken.class);
            //判断csrfToken是否存在
            if(csrfToken==null){
                return true;
            }
            if(csrfToken.create()){
                CsrfTokenEntity token = csrfTokenRepository.generateToken(request);
                csrfTokenRepository.saveToken(token, request, response);
                request.setAttribute(token.getParameterName(), token);
                return true;
            }else{
                CsrfTokenEntity token = csrfTokenRepository.loadToken(request);
                String actualToken = request.getHeader(token.getHeaderName());
                if(StringUtils.isEmpty(actualToken)){
                    actualToken = request.getParameter(token.getParameterName());
                }
                //token不存在或错误(返回错误)
                if(actualToken==null || !actualToken.equals(token.getToken())){

                    /*
                    处理错误信息
                    */
                    logger.error("CsrfToken error!");

                }else{
                    csrfTokenRepository.deleteToken(token,request,response);
                    return true;
                }



            }

        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }
}
